﻿using System;
using System.Data;
using System.Web.Caching;
using System.Web.UI;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.Data;
using NguyenHoa.Domains;
using NguyenHoa.Services;
using NguyenHoa.Web.App_Code;

namespace NguyenHoa.Web.Admin
{
  public partial class SurveyPage : AdminBasePage
  {
    #region Properties

    private string m_innerError = string.Empty;
    private string CACHE_CHOICE = "ChoiceCache";

    internal override int RequiredPermission
    {
      get
      {
        return (int)FunctionList.SystemSetting;
      }
    }
    #endregion

    #region Events

    protected void Page_Load(object sender, EventArgs e)
    {
      xdsLanguage.DataFile = xdsType.DataFile = XmlStatusFile;
      if (!IsCallback && !IsPostBack)
      {
        LoadSurvey();
        ClearCache();
      }
      if (gvChoice.IsCallback)
        LoadSurvey();
      if (gvEditChoice.IsCallback)
        LoadChoice();
    }

    protected void cbxLanguage_DataBound(object sender, EventArgs e)
    {
      cbxLanguage.Value = CurrentLanguage.Id;
    }

    protected void cbxType_DataBound(object sender, EventArgs e)
    {
      if (cbxType.Items.Count > 0)
      {
        cbxType.Value = cbxType.Items[0].Value;
      }
    }

    protected void gvChoice_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e)
    {
      string[] para = e.Parameters.Split('|');
      int surveyId;
      switch (para[0])
      {
        case "Save":
          m_innerError = "Save|" + SaveSurvey();
          LoadSurvey();
          break;
        case "Delete":
          int.TryParse(para[1], out surveyId);
          m_innerError = DeleteSurvey(surveyId);
          LoadSurvey();
          break;
        case "Active":
          bool active;
          int.TryParse(para[1], out surveyId);
          bool.TryParse(para[2], out active);
          m_innerError = ActiveSurvey(surveyId, active);
          LoadSurvey();
          break;
      }
    }

    protected void gvChoice_CustomJSProperties(object sender, ASPxGridViewClientJSPropertiesEventArgs e)
    {
      e.Properties["cpInnerError"] = m_innerError;
    }

    protected void gvEditChoice_CustomCallback(object sender, ASPxGridViewCustomCallbackEventArgs e)
    {
      string[] para = e.Parameters.Split('|');
      if (para[0] == "ClearCache")
      {
        ClearCache();
        LoadChoice();
      }
    }

    protected void gvEditChoice_CustomJSProperties(object sender, ASPxGridViewClientJSPropertiesEventArgs e)
    {
      e.Properties["cpInnerError"] = m_innerError;
    }

    protected void gvEditChoice_RowDeleting(object sender, ASPxDataDeletingEventArgs e)
    {
      int choiceId = 0;
      int.TryParse(e.Keys["Id"].ToString(), out choiceId);
      m_innerError = "Edit|";
      m_innerError += DeleteChoice(choiceId);
      ASPxGridView grid = sender as ASPxGridView;
      e.Cancel = true;
      grid.CancelEdit();
      LoadChoice();
    }

    protected void gvEditChoice_RowInserting(object sender, ASPxDataInsertingEventArgs e)
    {
      ASPxGridView grid = sender as ASPxGridView;
      int choiceId = 0;
      string name = (e.NewValues["Name"] != null) ? e.NewValues["Name"].ToString() : string.Empty;
      m_innerError = "Edit|";
      if (string.IsNullOrEmpty(name))
      {
        m_innerError += String.Format(Resources.Messages.ERR0007, Resources.Strings.Name);
        goto FINISH;
      }
      m_innerError += SaveChoice(choiceId, name);
    FINISH:
      e.Cancel = true;
      grid.CancelEdit();
      LoadChoice();
    }

    protected void gvEditChoice_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
    {
      ASPxGridView grid = sender as ASPxGridView;
      int choiceId = 0;
      string name = (e.NewValues["Name"] != null) ? e.NewValues["Name"].ToString() : string.Empty;
      m_innerError = "Edit|";
      if (string.IsNullOrEmpty(name))
      {
        m_innerError += String.Format(Resources.Messages.ERR0007, Resources.Strings.Name);
        goto FINISH;
      }
      int.TryParse(e.Keys["Id"].ToString(), out choiceId);
      m_innerError += SaveChoice(choiceId, name);
    FINISH:
      e.Cancel = true;
      grid.CancelEdit();
      LoadChoice();
    }
    #endregion

    #region Methods

    #region Survey Methods
    private void LoadSurvey()
    {
      int languageId = CurrentLanguage.Id;
      if (cbxLanguage.Value != null)
        int.TryParse(cbxLanguage.Value.ToString(), out languageId);
      DataSet ds = new SurveyService().GetByLanguage(languageId);
      if (ds.Tables.Count > 0 && ds.Tables[0] != null)
      {
        foreach (DataRow survey in ds.Tables[0].Rows)
        {
          //Active Question
          bool isActive = (survey["IsActive"] != DBNull.Value) ? Convert.ToBoolean(survey["IsActive"]) : false;
          int surveyId = (survey["Id"] != DBNull.Value) ? Convert.ToInt32(survey["Id"]) : 0;
          if (surveyId <= 0) continue;
          string rdoShowOnHome = Resources.Strings.ShowOnHome + "  ";
          rdoShowOnHome += "<input type='radio' name='rdo_'" + surveyId + " ";
          rdoShowOnHome += (isActive) ? "checked='checked' " : " ";
          rdoShowOnHome += "onclick=\"activeSurvey('" + surveyId + "', this.checked);\"";
          rdoShowOnHome += "></input>";
          survey["ShowOnHome"] = rdoShowOnHome;

          //Survey Type
          string type = (survey["Type"] != DBNull.Value) ? survey["Type"].ToString() : string.Empty;
          survey["DisplayType"] = GetItemDescription(type, "Items/SurveyType/Status");

          //Survey Result
          if (ds.Tables.Count > 1 && ds.Tables[1] != null)
          {
            DataRow[] choiceList = ds.Tables[1].Select("SurveyId=" + surveyId);
            string html = "<tr>";
            html += "<td rowspan='" + choiceList.Length + "'>";
            html += Resources.Strings.SurveyResult + "</td>";
            for (int i = 0; i < choiceList.Length; i++)
            {
              DataRow choice = choiceList[i];
              if (i > 0)
              {
                html += "<tr>";
              }
              html += "<td >" + choice["Name"] + "</td>";
              html += "<td align='right'>" + choice["Value"] + "</td>";
              html += "</tr>";
            }
            survey["SurveyResult"] = html;
          }
        }
      }

      gvChoice.DataSource = ds;
      gvChoice.DataBind();

    }

    private string ActiveSurvey(int surveyId, bool isActive)
    {
      try
      {
        if (isActive)
          new SurveyService().SetSurveyActive(surveyId);
      }
      catch (Exception ex)
      {
        WriteLog("SurveyView.aspx::Active Survey", ex);
        return Resources.Messages.ERR0004;
      }
      return string.Empty;
    }

    private string SaveSurvey()
    {
      SurveyService service = new SurveyService();
      Survey survey;
      try
      {
        int surveyId;
        int.TryParse(hfSurveyId.Value, out surveyId);
        string type = (cbxType.Value != null) ? cbxType.Value.ToString() : SurveyChoiceType.Single;
        int languageId = (cbxLanguageEdit.Value != null) ? Convert.ToInt32(cbxLanguageEdit.Value) : CurrentLanguage.Id;
        using (ConnectionScope.CreateTransaction())
        {
          if (surveyId > 0)
          {
            survey = service.GetById(surveyId);
            if (survey == null)
              return Resources.Messages.ERR0003;
          }
          else
          {
            survey = new Survey();
            survey.CreatedDate = DateTime.Now;
            survey.CreatedBy = CurrentUser.Fullname;
          }
          survey.Type = type;
          survey.LanguageId = languageId;
          survey.Question = mmQuestion.Text;
          //Checking whether there is an active survey of this language or not
          TList<Survey> activeList = service.GetActiveByLanguage(survey.LanguageId);
          if (activeList.Count > 0)
          {
            survey.IsActive = false;
          }
          service.Save(survey);

          if (Cache[CACHE_CHOICE] != null)
          {
            TList<SurveyDetail> choiceList = Cache[CACHE_CHOICE] as TList<Domains.SurveyDetail>;
            if (choiceList != null)
            {
              foreach (SurveyDetail choice in choiceList)
              {
                choice.Id = 0;
                choice.SurveyId = survey.Id;
              }
              new SurveyDetailService().Save(choiceList);
              ClearCache();
            }
          }

          ConnectionScope.Complete();
        }
        GlobalCache.Instance.SurveyQuestion = null;
      }
      catch (Exception ex)
      {
        WriteLog("SurveyView.aspx::Save Survey", ex);
        return Resources.Messages.ERR0004;
      }
      return "Id|" + survey.Id;
    }

    private string DeleteSurvey(int surveyId)
    {
      try
      {
        new SurveyService().Delete(surveyId);
        GlobalCache.Instance.SurveyQuestion = null;
      }
      catch (Exception ex)
      {
        WriteLog("SurveyView.aspx::Delete Survey", ex);
        return Resources.Messages.ERR0004;
      }
      return string.Empty;
    }
    #endregion

    #region Choices Methods
    private void LoadChoice()
    {
      int surveyId = 0;
      int.TryParse(hfSurveyId.Value, out surveyId);
      if (surveyId == 0)
      {
        if (Cache[CACHE_CHOICE] != null)
        {
          gvEditChoice.DataSource = Cache[CACHE_CHOICE];
        }
        else
        {
          TList<Domains.SurveyDetail> choiceList = new TList<SurveyDetail>();
          gvEditChoice.DataSource = choiceList;
          SetCacheExpire(choiceList);
        }
      }
      else
      {
        gvEditChoice.DataSource = new SurveyDetailService().GetBySurveyId(surveyId);
      }
      gvEditChoice.DataBind();
    }

    private string SaveChoice(int choiceId, string name)
    {
      try
      {
        int surveyId;
        int.TryParse(hfSurveyId.Value, out surveyId);
        SurveyDetailService service = new SurveyDetailService();
        SurveyDetail choice;

        #region Creating new survey
        if (surveyId == 0)
        {
          if (Cache[CACHE_CHOICE] != null)
          {
            TList<SurveyDetail> choiceList = Cache[CACHE_CHOICE] as TList<SurveyDetail>;
            if (choiceList != null)
            {
              if (choiceId > 0)
              {
                choice = choiceList.Find("Id", choiceId);
                if (choice == null)
                  return Resources.Messages.ERR0003;
                choice.Name = name;
              }
              else
              {
                choice = new SurveyDetail();
                choice.Type = SurveyDetailType.Choice;
                choice.LastModified = DateTime.Now;
                choice.Id = choiceList.Count + 1;
                choice.Name = name;
                choiceList.Add(choice);
              }
              return string.Empty;
            }
          }
          return Resources.Messages.ERR0003;
        }
        #endregion

        #region Edit existed survey
        if (choiceId > 0) //Edit choice
        {
          choice = service.GetById(choiceId);
          if (choice == null)
            return Resources.Messages.ERR0003;
        }
        else //Save choice
        {
          choice = new SurveyDetail();
          choice.Type = SurveyDetailType.Choice;
          choice.SurveyId = surveyId;
        }
        choice.LastModified = DateTime.Now;
        choice.Name = name;
        service.Save(choice);
        GlobalCache.Instance.SurveyOptions = null;
        #endregion
      }
      catch (Exception ex)
      {
        WriteLog("SurveyView.aspx::Save Choice", ex);
        return Resources.Messages.ERR0004;
      }
      return string.Empty;
    }

    private string DeleteChoice(int choiceId)
    {
      try
      {
        if (string.IsNullOrEmpty(hfSurveyId.Value) && Cache[CACHE_CHOICE] != null)
        {
          TList<SurveyDetail> choiceList = Cache[CACHE_CHOICE] as TList<SurveyDetail>;
          if (choiceList != null)
          {
            choiceList.Remove(choiceList.Find("Id", choiceId));
            return string.Empty;
          }
        }
        new SurveyDetailService().Delete(choiceId);
        GlobalCache.Instance.SurveyOptions = null;
      }
      catch (Exception ex)
      {
        WriteLog("SurveyView.aspx::Delete Choice", ex);
        return Resources.Messages.ERR0004;
      }
      return string.Empty;
    }

    #endregion

    #region Tracking page cache expire

    private CacheItemRemovedCallback onCacheExpire;

    private void SetCacheExpire(object tbl)
    {
      onCacheExpire = new CacheItemRemovedCallback(CacheExpireEvent);
      Cache.Insert(CACHE_CHOICE, tbl, null, DateTime.Now.AddMinutes(GlobalCache.Instance.CachedExpiredDuration),
       Cache.NoSlidingExpiration, CacheItemPriority.Normal, onCacheExpire);
    }

    private void CacheExpireEvent(string key, object value, CacheItemRemovedReason reason)
    {
      try
      {
        Cache.Remove(CACHE_CHOICE);
      }
      catch (Exception ex)
      {
        WriteLog("BookingSupport.cs::CacheExpireEvent", ex);
      }
    }

    private void ClearCache()
    {
      Cache.Remove(CACHE_CHOICE);
    }
    #endregion
    #endregion
  }
}
